import 'dart:convert';
import 'dart:io';

import 'package:base/net/client.dart';
import 'package:base/net/data_type.dart';
import 'package:base/net/method.dart';
import 'package:base/net/net_error_code.dart';
import 'package:base/net/net_exception.dart';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';

class HttpRequest {
  late Client _client;

  static const CODE = "retCode";
  static const MSG = "retMessage";

  static const bool inProduction =
      const bool.fromEnvironment("dart.vm.product");

  HttpRequest({
    BaseOptions? options,
    String baseUrl = "",
    Map<String, dynamic> headers = const {},
  }) {
    _client = Client(
      options: options,
      baseUrl: baseUrl,
      headers: headers,
    );
  }

  ///通用请求
  Future doRequest(String path, Map<String, dynamic> params,
      {Method method = Method.POST,
      dynamic data,
      String? tag,
      Map<String, dynamic> headers = const {},
      DataType type = DataType.JSONObject}) async {
    if (!inProduction) {
      print("$path:请求数据:" + params.toString());
    }
    Response<String> response = await _client.httpRequest(
      path,
      data: data,
      queryParameters: params,
      headers: headers,
      tag: tag,
    );

    return _doResponse(path, response, type: type);
  }

  ///通用上传
  Future commonFileUpload(BuildContext context, String url, List<String> files,
      {queryParameters,
      ProgressCallback? onSendProgress,
      DataType type = DataType.JSONObject}) async {
    Response<String> response = await _client.upload(url, files,
        queryParameters: queryParameters, onSendProgress: (value, total) {
      if (onSendProgress != null) {
        onSendProgress(value, total);
      }
    });

    return _doResponse(url, response, type: type);
  }

// ///通用下载
  Future<File> commonDownload(
    url,
    savePath, {
    ProgressCallback? onReceiveProgress,
  }) {
    return _client.download(
      url,
      savePath,
      onReceiveProgress: onReceiveProgress,
    );
  }

  ///
  /// response通用处理
  ///
  dynamic _doResponse(String url, Response<String> response,
      {DataType type = DataType.JSONObject}) {
    String? data = response.data;
    int? statusCode = response.statusCode;

    if (data == null || statusCode == null) {
      throw NetException(NetErrorCode.EMPTY_DATA, "无数据返回");
    }

    if (statusCode == 200) {
      if (!inProduction) {
        print("$url:返回数据:" + data.toString());
      }
      if (type == DataType.JSONObject) {
        return json.decode(data);
      } else if (type == DataType.JSONArray) {
        return json.decode(data) as List;
      } else {
        return response.data;
      }
    } else {
      if (!inProduction) {
        print("$url:errorCode:" + statusCode.toString());
        print("$url:error:" + data.toString());
      }
      String? message;
      String? code;

      if (response.data != null) {
        Map<String, dynamic> errorJson = json.decode(data);
        code = errorJson[CODE]?.toString();
        message = errorJson[MSG]?.toString();
      } else {
        code = response.statusCode.toString();
        switch (response.statusCode) {
          case NetErrorCode.SERVER_NOT_FOUND:
            message = "未知服务请求,请联系管理员";
            break;
          case NetErrorCode.SEVER_ERROR:
            message = "服务器异常,请稍后重试";
            break;
          case NetErrorCode.CONNECT_TIMEOUT:
            message = "连接超时,请检查您的网络";
            break;

          case NetErrorCode.SOCKET_ERROR:
            message = "无法连接服务器,请稍后重试";
            break;
          case NetErrorCode.NET_ERROR:
            message = "网络异常,请检查您的网络";
            break;
          case NetErrorCode.HTTP_UNKNOWN_CODE:
            message = "未知错误";
            break;
          default:
            break;
        }
      }

      throw NetException(
          code ?? NetErrorCode.HTTP_UNKNOWN_CODE, message ?? "未知错误");
    }
  }
}
